'use client'
import type { EventEmitter } from 'ahooks/es/useEventEmitter'
import cn from 'classnames'
import Textarea from 'rc-textarea'
import type { FC } from 'react'
import React, { useEffect, useMemo, useRef } from 'react'
import { useTranslation } from 'react-i18next'
import Answer from './answer'
import Question from './question'
import s from './style.module.css'
import type { FeedbackFunc } from './type'
import { IconStop } from '@/app/components/chat/xf-voice/Icon'
import { ChatContext } from '@/app/components/chat/chat-context'
import ChatImageUploader from '@/app/components/base/image-uploader/chat-image-uploader'
import { useImageFiles } from '@/app/components/base/image-uploader/hooks'
import ImageList from '@/app/components/base/image-uploader/image-list'
import Toast from '@/app/components/base/toast'
import Tooltip from '@/app/components/base/tooltip'
import { getChatBridge } from '@/app/components/bridge'
import XFVoice from '@/app/components/chat/xf-voice/VoiceInput'
import type { ChatItem, VisionFile, VisionSettings } from '@/types/app'
import { TransferMethod } from '@/types/app'

export type IChatProps = {
  chatList: ChatItem[]
  eventEmitter: EventEmitter<{ type: string;data: ChatItem }>
  /**
   * Whether to display the editing area and rating status
   */
  feedbackDisabled?: boolean
  /**
   * Whether to display the input area
   */
  isHideSendInput?: boolean
  onFeedback?: FeedbackFunc
  checkCanSend?: () => boolean
  onSend?: (message: string, files: VisionFile[]) => void
  useCurrentUserAvatar?: boolean
  isResponding?: boolean
  controlClearQuery?: number
  visionConfig?: VisionSettings
  onStopResponding?: () => void
}
const config = {
  showStopResponding: false,
}
const Chat: FC<IChatProps> = ({
  chatList,
  feedbackDisabled = false,
  isHideSendInput = false,
  onFeedback,
  checkCanSend,
  onSend = () => {
  },
  useCurrentUserAvatar,
  isResponding,
  onStopResponding,
  controlClearQuery,
  visionConfig,
  eventEmitter,
}) => {
  const { t } = useTranslation()
  const { notify } = Toast
  const isUseInputMethod = useRef(false)

  const [query, setQuery] = React.useState('')
  const handleContentChange = (e: any) => {
    const value = e.target.value
    setQuery(value)
  }

  const logError = (message: string) => {
    notify({
      type: 'error',
      message,
      duration: 3000,
    })
  }

  const valid = () => {
    if (!query || query.trim() === '') {
      logError('发送消息不能为空！')
      return false
    }
    return true
  }

  useEffect(() => {
    if (controlClearQuery)
      setQuery('')
  }, [controlClearQuery])
  const {
    files,
    onUpload,
    onRemove,
    onReUpload,
    onImageLinkLoadError,
    onImageLinkLoadSuccess,
    onClear,
  } = useImageFiles()
  const sendText = (text: string) => {
    if (!text || text.trim() === '') {
      logError('发送消息不能为空！')
      return {
        code: -1,
        message: '发送消息不能为空！',
      }
    }
    if ((checkCanSend && !checkCanSend())) {
      return {
        code: -1,
        message: '消息发送失败！',
      }
    }

    onSend(text, [])
    return null
  }
  useEffect(() => {
    return getChatBridge().on('send2ai', ({ data }) => {
      return sendText(data)
    })
  }, [])
  const handleVoiceSend = (text: string) => {
    sendText(text)
  }
  const handleSend = () => {
    if (!valid() || (checkCanSend && !checkCanSend()))
      return

    onSend(query, files.filter(file => file.progress !== -1).map(fileItem => ({
      type: 'image',
      transfer_method: fileItem.type,
      url: fileItem.url,
      upload_file_id: fileItem.fileId,
    })))
    if (!files.find(item => item.type === TransferMethod.local_file && !item.fileId)) {
      if (files.length)
        onClear()

      if (!isResponding)
        setQuery('')
    }
  }

  const handleKeyUp = (e: any) => {
    if (e.code === 'Enter') {
      e.preventDefault()
      // prevent send message when using input method enter
      if (!e.shiftKey && !isUseInputMethod.current)
        handleSend()
    }
  }

  const handleKeyDown = (e: any) => {
    isUseInputMethod.current = e.nativeEvent.isComposing
    if (e.code === 'Enter' && !e.shiftKey) {
      setQuery(query.replace(/\n$/, ''))
      e.preventDefault()
    }
  }
  const chatCtxValue = useMemo(() => ({
    sendText,
    eventEmitter,
  }), [eventEmitter, sendText])

  return (
    <ChatContext.Provider value={chatCtxValue}>
      <div className={cn(!feedbackDisabled && 'px-3.5', 'h-full')}>
        {/* Chat List */}
        <div className="h-full space-y-[30px] sm:space-y-[20px] x-chat-list">
          {chatList.map((item) => {
            if (item.isAnswer) {
              const isLast = item.id === chatList[chatList.length - 1].id
              return <Answer
                key={item._key ?? item.id}
                item={item}
                feedbackDisabled={feedbackDisabled}
                onFeedback={onFeedback}
                isResponding={isResponding && isLast}
              />
            }
            return (
              <Question
                key={item._key ?? item.id}
                id={item.id}
                content={item.content as string}
                useCurrentUserAvatar={useCurrentUserAvatar}
                imgSrcs={(item.message_files && item.message_files?.length > 0) ? item.message_files.map(item => item.url) : []}
              />
            )
          })}
        </div>
        {
          !isHideSendInput && (
            <div className={cn(!feedbackDisabled && '!left-3.5 !right-3.5', 'absolute z-10 bottom-0 left-0 right-0')}>
              <div
                className={cn('p-[5.5px] pb-[40px] pt-[12px] min-h-[122px] max-h-[150px] bg-white border-[1.5px] border-gray-240 rounded-xl overflow-y-hidden', s.input_wrapper)}
              >
                {
                  config.showStopResponding && (
                    <div className='absolute top-[-24px] center mb-2 flex justify-center'>
                      <button className="flex" onClick={onStopResponding}>
                        <IconStop className='mr-[5px] h-3.5 w-3.5 text-gray-500' />
                        <span className='text-xs font-normal text-gray-500'>停止响应</span>
                      </button>
                    </div>
                  )
                }
                {
                  visionConfig?.enabled && (
                    <>
                      <div className="absolute bottom-2 left-2 flex items-center">
                        <ChatImageUploader
                          settings={visionConfig}
                          onUpload={onUpload}
                          disabled={files.length >= visionConfig.number_limits}
                        />
                        <div className="mx-1 w-[1px] h-4 bg-black/5"/>
                      </div>
                      <div className="pl-[52px]">
                        <ImageList
                          list={files}
                          onRemove={onRemove}
                          onReUpload={onReUpload}
                          onImageLinkLoadSuccess={onImageLinkLoadSuccess}
                          onImageLinkLoadError={onImageLinkLoadError}
                        />
                      </div>
                    </>
                  )
                }
                <Textarea
                  className={`
                  block w-full px-2 pr-[4px] py-[7px] leading-5 max-h-none text-sm text-gray-700 outline-none appearance-none resize-none
                  ${visionConfig?.enabled && 'pl-12'}
                `}
                  value={query}
                  onChange={handleContentChange}
                  onKeyUp={handleKeyUp}
                  onKeyDown={handleKeyDown}
                  style={{ height: 100 }}
                />
                <div className="absolute bottom-2 right-2 flex items-center h-8">
                  {/* <div className={`${s.count} mr-4 h-5 leading-5 text-sm bg-gray-50 text-gray-500`} */}
                  {/* >{query.trim().length}</div> */}
                  <div className="mr-1">
                    <XFVoice onRecordEnd={handleVoiceSend}/>
                  </div>
                  <Tooltip
                    selector="send-tip"
                    htmlContent={
                      <div>
                        <div>{t('common.operation.send')} Enter</div>
                        <div>{t('common.operation.lineBreak')} Shift Enter</div>
                      </div>
                    }
                  >
                    <div className={`${s.sendBtn} w-8 h-8 cursor-pointer rounded-md`} onClick={handleSend}/>
                  </Tooltip>
                </div>
              </div>
            </div>
          )
        }
      </div>
    </ChatContext.Provider>
  )
}

export default React.memo(Chat)
